/*
 * @(#)PermissionTag.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */

package com.dcivision.framework.taglib.logic;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.PermissionManager;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;

/**
  PermissionTag.java

  <p>This class is to extend the BodyTagSupport provided by Apache Struts.<p>
  <p>Modification in "struts-logic.tld"<br>
  <pre>
     [ADDED]
     &lt;tag&gt;
     &lt;name&gt;permission&lt;/name&gt;
     &lt;tagclass&gt;com.dcivision.framework.taglib.logic.PermissionTag&lt;/tagclass&gt;
     &lt;bodycontent&gt;JSP&lt;/bodycontent&gt;
     &lt;attribute&gt;
     &lt;name&gt;functionCode&lt;/name&gt;
     &lt;required&gt;true&lt;/required&gt;
     &lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;
     &lt;/attribute&gt;
     &lt;attribute&gt;
     &lt;name&gt;right&lt;/name&gt;
     &lt;required&gt;true&lt;/required&gt;
     &lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;
     &lt;/attribute&gt;
     &lt;/tag&gt;
  </pre>
  </p>

    @author          Phoebe Wong
    @company         DCIVision Limited
    @creation date   09/07/2003
    @version         $Revision: 1.18.26.2 $
*/

public class PermissionTag extends BodyTagSupport {
  
  private static final Log log = LogFactory.getLog(PermissionTag.class);

  public static final String REVISION = "$Revision: 1.18.26.2 $";

  public static final String SEPARATOR = "<##########>";
  private String sObjectType;
  private Integer nObjectID;
  private String sFunctionCode;
  private String sRight;

  /**
   * Constructor
   */
  public PermissionTag() {
    super();
  }

  public String getFunctionCode() {
    return this.sFunctionCode;
  }

  public void setFunctionCode(String sFunctionCode) {
    this.sFunctionCode = sFunctionCode;
  }

  public String getRight() {
    return this.sRight;
  }

  public void setRight(String sRight) {
    this.sRight = sRight;
  }

  public String getObjectType() {
    return this.sObjectType;
  }

  public void setObjectType(String objectType) {
    this.sObjectType = objectType;
  }

  public Integer getObjectID() {
    return this.nObjectID;
  }

  public void setObjectID(Integer objectID) {
    this.nObjectID = objectID;
  }

  /**
   * Method called at start of tag
   * @return a EVAL_BODY_BUFFERED
   */
  
  public int doStartTag() throws JspException {
    return EVAL_BODY_BUFFERED;
  }

  /**
   * Method called by the Container to check permission
   */
  public boolean checkPermission() throws ApplicationException {
    SessionContainer sessionCon = (SessionContainer)pageContext.getSession().getAttribute(GlobalConstant.SESSION_CONTAINER_KEY);
    if("W".equals(this.sObjectType)){
      return(this.workflowCheckPermission());
    }
    if (Utility.isEmpty(this.sObjectType)) {
      return(sessionCon == null ? false : sessionCon.hasAccessRight(sFunctionCode, sRight));
    } else {
      PermissionManager permManager = sessionCon.getPermissionManager();
      if (permManager == null) {
        log.debug("NO PERMISSION MANAGER");
        return(false);
      }
      // Get the access right from cache if it has.
      if (pageContext.getRequest().getAttribute("AR_" + this.sObjectType + "_" + this.nObjectID + "_" + this.sRight) != null) {
        return(((Boolean)pageContext.getRequest().getAttribute("AR_" + this.sObjectType + "_" + this.nObjectID + "_" + this.sRight)).booleanValue());
      }
      java.sql.Connection conn = (java.sql.Connection)pageContext.getRequest().getAttribute(GlobalConstant.DB_KEY);
      boolean hasRight = false;
      if (conn == null) {
        hasRight = permManager.hasAccessRight(this.sObjectType, this.nObjectID, this.sRight);
      } else {
        hasRight = permManager.hasAccessRight(conn, this.sObjectType, this.nObjectID, this.sRight);
      }
      // Cache the access right.
      pageContext.getRequest().setAttribute("AR_" + this.sObjectType + "_" + this.nObjectID + "_" + this.sRight, new Boolean(hasRight));
      return(hasRight);
    }
  }
  /**
   * Method called by the Container to check permission
   */
  public boolean workflowCheckPermission() throws ApplicationException {
    SessionContainer sessionCon = (SessionContainer)pageContext.getSession().getAttribute(GlobalConstant.SESSION_CONTAINER_KEY);
    boolean hasRight=false;
    boolean user_hasRight=false;
    hasRight=sessionCon == null ? false : sessionCon.hasAccessRight(sFunctionCode, sRight);
    if (!Utility.isEmpty(this.sObjectType)) {
      PermissionManager permManager = sessionCon.getPermissionManager();
      if (permManager == null) {
        log.debug("NO PERMISSION MANAGER");
        return(false);
      }
      // Get the access right from cache if it has.
      if (pageContext.getRequest().getAttribute("AR_" + this.sObjectType + "_" + this.nObjectID + "_" + this.sRight) != null) {
        return(((Boolean)pageContext.getRequest().getAttribute("AR_" + this.sObjectType + "_" + this.nObjectID + "_" + this.sRight)).booleanValue());
      }
      java.sql.Connection conn = (java.sql.Connection)pageContext.getRequest().getAttribute(GlobalConstant.DB_KEY);
      if (conn == null) {
      user_hasRight = permManager.hasAccessRight(this.sObjectType, this.nObjectID, this.sRight);
      } else {
      user_hasRight = permManager.hasAccessRight(conn, this.sObjectType, this.nObjectID, this.sRight);
      }
      if(hasRight&&user_hasRight){
      hasRight=true;
      }else{
      hasRight=false;
      }
      // Cache the access right.
      pageContext.getRequest().setAttribute("AR_" + this.sObjectType + "_" + this.nObjectID + "_" + this.sRight, new Boolean(hasRight));
      //return(hasRight);
    }
    return(hasRight);
  }

  /**
   * Method Called at end of tag
   * If the permission is true display the first statment
   * Else print the second statment.
   * @return either SKIP_PAGE
   */
  
  public int doEndTag() throws JspException {
    // Retrieve function code if it is not set.
    if (Utility.isEmpty(sFunctionCode)) {
      setFunctionCode((String) pageContext.getRequest().getAttribute(GlobalConstant.FUNCTION_CODE_KEY));
    }

    if (bodyContent != null) {
      String sTmp = bodyContent.getString();
      String[] asResult = null;

      if (sTmp.indexOf(SEPARATOR) < 0) {
        asResult = TextUtility.splitString(sTmp, "\n");
      } else {
        String[] tmpAry = TextUtility.splitString(sTmp, SEPARATOR);
        asResult = new String[3];
        asResult[1] = tmpAry[0];
        if (tmpAry.length == 2) {
          asResult[2] = tmpAry[1];
        }
      }

      try {
        JspWriter out = pageContext.getOut();

        if (checkPermission()) {
          out.println(asResult[1]);
        } else if (asResult.length >= 2) {
          out.println(asResult[2]);
        }
      } catch (Exception ioe) {
        throw new JspException(ioe);
      }
    }

    return EVAL_PAGE;
  }

  
  public void release() {
    super.release();
    sFunctionCode = null;
    sRight = null;
    sObjectType = null;
    nObjectID = null;
  }
}
